/******************************************************************
 * Created by: GOH CHEE HONG                                      
 * Date of Creation: 22/AUG/2008     
 * Date of last modification: 
 *                                                                
 * Description: A form showing the status of friends
 ******************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using Pbdms.Common;
using System.IO;
using System.Net;
using Pbdms.BusinessLogic.FileTransfer;
using Pbdms.Common.BaseClass;
namespace Pbdms.Forms.Views
{
    public partial class FrmBuddyStatus : newForms
    {
        
        public delegate void DelegateWorker(object sender, string args);
        public delegate void updateBudddy(object sender,string name, string type);
        public Thread updateBuddyProcess;
        ImageList pictureImage = new ImageList();
        public BusinessLogic.PeerMS.PeerTrackingManager peerTrackingManager;
        private TreeNode authenticatedNode;
        private TreeNode offlineNode;
        private TreeNode unTrustedNode;
        public FrmBuddyStatus()
        {
            InitializeComponent();
            Init_Images();
            Load_default();
            //Load_buddies();
            this.treeBuddies.MouseUp += new MouseEventHandler(treeBuddies_MouseUp);
            peerTrackingManager = new Pbdms.BusinessLogic.PeerMS.PeerTrackingManager(Program.networkCtrller);
            this.treeBuddies.HideSelection = false;
            
            peerTrackingManager.addNewTracker += new EventHandler(peerTrackingManager_addNewTracker);
            peerTrackingManager.deleteNewTracker += new EventHandler(peerTrackingManager_deleteNewTracker);
            peerTrackingManager.pollingStarts += new EventHandler(peerTrackingManager_authenticatingStarts);
            peerTrackingManager.pollingFailed += new EventHandler(peerTrackingManager_authenticatingFailed);
            peerTrackingManager.pollingSuccess += new EventHandler(peerTrackingManager_authenticatingSuccess);
        }

        /// <summary>
        /// peertracker event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void peerTrackingManager_authenticatingSuccess(object sender, EventArgs e)
        {
            try
            {
                if (InvokeRequired)
                {
                    EventHandler MessageWorker = new EventHandler(peerTrackingManager_authenticatingSuccess);
                    this.BeginInvoke(MessageWorker, new object[] { sender, e });
                }
                else
                {
                    BusinessLogic.PeerMS.PeerTracker peer = (BusinessLogic.PeerMS.PeerTracker)sender;
                    moveTreeNode(peer.ID, "offline","online");
                    //updateNode(peer.ID, "online", "Auth Success");
                    IPAddress ip=peer.getIpAddress();
                    string ipStr = null;
                    if (ip != null)
                    {
                        ipStr = ip.ToString();
                    }
                    Program.friendControl.setVerifiedFriendIP(peer.ID,ipStr);
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// peer tracker authenticate event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void peerTrackingManager_authenticatingFailed(object sender, EventArgs e)
        {
            try
            {
                if (InvokeRequired)
                {
                    EventHandler MessageWorker = new EventHandler(peerTrackingManager_authenticatingFailed);
                    this.BeginInvoke(MessageWorker, new object[] { sender, e });
                }
                else
                {
                    
                    BusinessLogic.PeerMS.PeerTracker peer = (BusinessLogic.PeerMS.PeerTracker)sender;
                    //set a friend to be offline
                    moveTreeNode(peer.ID, "online","offline");
                    peer.setIpAddress(null);
                   
                    Program.friendControl.setLogOff(peer.ID);
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// peer tracker authenticate starts
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void peerTrackingManager_authenticatingStarts(object sender, EventArgs e)
        {
            try
            {
                if (InvokeRequired)
                {
                    EventHandler MessageWorker = new EventHandler(peerTrackingManager_authenticatingStarts);
                    this.BeginInvoke(MessageWorker, new object[] { sender, e });
                }
                else
                {
                    BusinessLogic.PeerMS.PeerTracker peer = (BusinessLogic.PeerMS.PeerTracker)sender;
                    
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// peer tracker delete event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void peerTrackingManager_deleteNewTracker(object sender, EventArgs e)
        {
            BusinessLogic.PeerMS.PeerTracker peer = (BusinessLogic.PeerMS.PeerTracker)sender;
            deleteNode(peer.ID);
         
        }


        /// <summary>
        /// peer tracker add new tracker event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void peerTrackingManager_addNewTracker(object sender, EventArgs e)
        {
            BusinessLogic.PeerMS.PeerTracker peer = (BusinessLogic.PeerMS.PeerTracker)sender;
            string id = BusinessLogic.DataController.BuddyController.create().selectIDBasedOnKeyIDFromDB(peer.ID);
            Common.DataObject.Buddy buddy = BusinessLogic.DataController.BuddyController.create().selectABuddyBasedOnIDFromDB(id);
            TreeNode node = null;
            if (peer.getTrusted() == true)
            {
                //set a node a offline
                node=offlineNode.Nodes.Add(peer.ID, buddy.Name, 1,1);
              
                offlineNode.ExpandAll();
            }
            else
            {
                //set a node as untrusted
                node=unTrustedNode.Nodes.Add(peer.ID, buddy.Name, 2, 2);
                unTrustedNode.ExpandAll();
            }
            
        }
        /// <summary>
        /// Images pre settings
        /// </summary>
        public void Init_Images()
        {
            pictureImage.Images.Add(Pbdms.Properties.Resources.online);
            pictureImage.Images.Add(Pbdms.Properties.Resources.offline);
            pictureImage.Images.Add(Pbdms.Properties.Resources.Untrusted);
            treeBuddies.ImageList = pictureImage;
           
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            // If there is an image and it has a location, 
            // paint it when the Form is repainted.

            base.OnPaint(e);
            expand();
        }
        private void Load_default()
        {
            
            authenticatedNode = treeBuddies.Nodes.Add("Online");
            authenticatedNode.Name = "Authenticated";
            authenticatedNode.ImageIndex = 0;
            authenticatedNode.SelectedImageIndex = 0;
            offlineNode = treeBuddies.Nodes.Add("Offline");
            offlineNode.Name = "Offline";
            offlineNode.ImageIndex = 1;
            offlineNode.SelectedImageIndex = 1;
            unTrustedNode = treeBuddies.Nodes.Add("Untrusted");
            unTrustedNode.Name = "Untrusted";
            unTrustedNode.ImageIndex = 2;
            unTrustedNode.SelectedImageIndex = 2;
        }
      
       
        
        private void FrmBuddyStatus_FormClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
          
            this.Hide();
            expand();

        }
        //expand each node of the treenode
        private  void expand()
        {

            authenticatedNode.ExpandAll();
            offlineNode.ExpandAll();
            unTrustedNode.ExpandAll();
        }

        //when user click on right button
        void treeBuddies_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                // Select the clicked node
                treeBuddies.SelectedNode = treeBuddies.GetNodeAt(e.X, e.Y);

                if (treeBuddies.SelectedNode != null && treeBuddies.SelectedNode.Parent != null)
                {
                    
                    string keyid = treeBuddies.SelectedNode.Name;
                    string id = BusinessLogic.DataController.BuddyController.create().selectIDBasedOnKeyIDFromDB(keyid);
                    Common.DataObject.Buddy buddy = BusinessLogic.DataController.BuddyController.create().selectABuddyBasedOnIDFromDB(id);
                    idToolStripMenuItem.Text = buddy.Name + "(Public key:" + buddy.KeyID + ")";
                    idToolStripMenuItem.Tag = keyid;
                    string DBid = BusinessLogic.DataController.SubscriptionInfoController.create().selectIDBasedOnChannelAndFriend("Recent activities", buddy.KeyID);
                    //check whether the feed is subscribed or not

                    subscribeToNewAdditionsToolStripMenuItem.Tag = buddy.KeyID + " Newest Library additions";

                    DBid = BusinessLogic.DataController.SubscriptionInfoController.create().selectIDBasedOnChannelAndFriend("Newest Library additions", buddy.KeyID);
                    if (DBid == null)
                    {
                        subscribeToNewAdditionsToolStripMenuItem.Text = "Subscribe to New Additions feed";
                    }
                    else
                    {
                        subscribeToNewAdditionsToolStripMenuItem.Text = "Unsubscribe New Additions feed";
                    }
                    if (treeBuddies.SelectedNode.Parent.Name.Equals("Authenticated"))
                    {
                        sendMsgBtn.Text = "Send an instant message";
                    }
                    else
                    {
                        sendMsgBtn.Text = "Send an offline message";
                    }
                    contextMenu.Show(treeBuddies, e.Location);
                }
         
            }
            else if (e.Button == MouseButtons.Left)
            {
                // Select the clicked node
                treeBuddies.SelectedNode = treeBuddies.GetNodeAt(e.X, e.Y);
                if (treeBuddies.SelectedNode != null && treeBuddies.SelectedNode.Parent != null)
                {
                    btnMsg.Enabled = true;
                    btnSend.Enabled = true;
                    btnSubscr.Enabled = true;
                    
                    string keyid = treeBuddies.SelectedNode.Name;
                    
                    btnSubscr.Tag = keyid;
                    string id = BusinessLogic.DataController.BuddyController.create().selectIDBasedOnKeyIDFromDB(keyid);
                    Common.DataObject.Buddy buddy = BusinessLogic.DataController.BuddyController.create().selectABuddyBasedOnIDFromDB(id);

                    string DBid = "";

                    subscribeToNewAdditionsToolStripMenuItem.Tag = buddy.KeyID + " Newest Library additions";

                    DBid = BusinessLogic.DataController.SubscriptionInfoController.create().selectIDBasedOnChannelAndFriend("Newest Library additions", buddy.KeyID);
                    //check if the database contains the subscription information
                    if (DBid == null)
                    {
                       btnSubscr.Text = "Subscribe";
                    }
                    else
                    {
                        btnSubscr.Text = "Unsubscribe";
                    }



                }
                else
                {
                    //invalid nodes
                    btnMsg.Enabled = false;
                    btnSend.Enabled = false;
                    btnSubscr.Enabled = false;
                }
            }
        }
        //subscribe method to new addition feed
        private void subscribeToNewAdditionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
          
            //get current selected node
            string key = (string)idToolStripMenuItem.Tag;
            /*
            string userid=BusinessLogic.DataController.BuddyController.create().selectIDFromDB(node.te);
            Common.DataObject.Buddy buddy = BusinessLogic.DataController.BuddyController.create().selectABuddyBasedOnIDFromDB(userid);
            DateTime defaulttime= new DateTime();
             * 
             */


            //check whether subscrbe or unsubscribe
            if (subscribeToNewAdditionsToolStripMenuItem.Text.Equals("Subscribe to New Additions feed"))
            {

                Program.mainForm.frmfeeds.subscManager.addSubscription("Newest Library additions", key);
                Common.GUI.MsgBoxOneButton msgForm = new Pbdms.Common.GUI.MsgBoxOneButton("Subscription successful", 'I');
                msgForm.ShowDialog();
            }
            else
            {

                BusinessLogic.RSS.Subscription subscription = (BusinessLogic.RSS.Subscription) Program.mainForm.frmfeeds.subscManager.arrSubscriptions[(string)subscribeToNewAdditionsToolStripMenuItem.Tag];

                Program.mainForm.frmfeeds.subscManager.removeSubscription(subscription);
                Common.GUI.MsgBoxOneButton msgForm = new Pbdms.Common.GUI.MsgBoxOneButton("Unsubscription successful", 'I');
                msgForm.ShowDialog();
            }
        }
     

        private void sendMsgBtn_Click(object sender, EventArgs e)
        {
            string key = (string)idToolStripMenuItem.Tag;

            
             
            if (sendMsgBtn.Text.Equals("Send an instant message"))
            {
                Tools.FrmInstantMsg fmMsg = new Tools.FrmInstantMsg();
                fmMsg.MdiParent = this.MdiParent;
                //set key id
                fmMsg.setID(key);
                fmMsg.setTitle();
                fmMsg.Show();
            }
            else
            {
                Pbdms.Forms.Tools.FrmOfflineMsg frmOffline = new Pbdms.Forms.Tools.FrmOfflineMsg();
                frmOffline.MdiParent = this.MdiParent;
                //set friend 
                frmOffline.addFriend(key);
                frmOffline.Show();
            }
        }
        /// <summary>
        /// send file event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendFileBtn_Click(object sender, EventArgs e)
        {
            DialogResult result = openFileDia.ShowDialog();
            string filelocation = null;
            //check if the file name valid
            if (result == DialogResult.OK)
            {
                //valid
                filelocation = openFileDia.FileName;
                try
                {
                    string key = (string)idToolStripMenuItem.Tag;
                    Common.DataObject.Buddy buddy = Program.friendControl.getAFriendByKeyID(key);
                   
                    FileInfo fileInfo = new FileInfo(filelocation);
                    //create a file transfer
                    FileTransferSenderGui fileTransfer = new FileTransferSenderGui(key,buddy.Name,fileInfo,Program.networkCtrller);
                       
             
                      
                    Program.mainForm.frmFileTransfer.MdiParent = Program.mainForm;
                    //add a file transfer to the form
                    Program.mainForm.frmFileTransfer.addControl(fileTransfer);
                    Program.mainForm.frmFileTransfer.Activate();

                    Program.mainForm.frmFileTransfer.Show();
                
                }
                catch
                {
                    MessageBox.Show("An unknown error occurred in sending a file");
                }
                
            }
        }

    
        private void button1_Click(object sender, EventArgs e)
        {
            peerTrackingManager.authenticateAll();
        }

        /// <summary>
        /// delete a treenode based on the key
        /// </summary>
        /// <param name="key"></param>
        public void deleteNode(string key)
        {
            lock (this)
            {
                TreeNode[] nodes = null;
              
                   
                nodes = treeBuddies.Nodes.Find(key, true);
                if (nodes != null)
                {
                    if (nodes.Length != 0)
                    {
                        nodes[0].Remove();
                    }
                }
            }
        }

        /// <summary>
        /// move a tree node to other parent
        /// </summary>moveTreeNode
        /// <param name="key"></param>
        /// <param name="type"></param>
        public Boolean moveTreeNode(string key,string source,string destination)
        {
            Common.DataObject.Buddy buddy= Program.friendControl.getAFriendByKeyID(key);
            if(buddy==null){
                return false; ;
            }
            lock (this)
            {
               
                TreeNode[] nodes = null;
                if (source.Equals("online"))
                {
                    nodes = authenticatedNode.Nodes.Find(key, true);
                }
                else if (source.Equals("offline"))
                {
                    nodes = offlineNode.Nodes.Find(key, true);
                }
                else if (source.Equals("untrusted"))
                {
                    nodes = unTrustedNode.Nodes.Find(key, true);
                }else if(source.Equals("all")){
                    nodes=treeBuddies.Nodes.Find(key,true);
                }
                if (nodes.Length == 0)
                {
                    return false;
                }
               
                nodes[0].Remove();
               
                if (destination.Equals("online"))
                {
                    authenticatedNode.Nodes.Add(key, buddy.Name, 0, 0);
                    authenticatedNode.ExpandAll();
                }
                else if (destination.Equals("offline"))
                {
                    offlineNode.Nodes.Add(key, buddy.Name, 1, 1);
                    offlineNode.ExpandAll();
                }
                else
                {   
                    unTrustedNode.Nodes.Add(key, buddy.Name, 2, 2);
                    unTrustedNode.ExpandAll();
                }
                
                return true;
                
            }
        }
        public override void changeName(string keyID, string oldName,string newName)
        {
            try
            {
                TreeNode[] node = treeBuddies.Nodes.Find(keyID, true);
                node[0].Text = newName;
            }
            catch
            {
                //failed to find
            }
        }
        /// <summary>
        /// update a treenode based on the keyid 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="type"></param>
        /// <param name="msg"></param>
        private void updateNode(string key,string type, string msg)
        {
            Common.DataObject.Buddy buddy= BusinessLogic.DataController.BuddyController.create().selectABuddyBasedOnKeyIDFromDB(key);
            if(buddy==null){
                return;
            }
            lock (this)
            {
                TreeNode[] nodes = null;
                if (type.Equals("online"))
                {
                    //move to online
                    nodes = authenticatedNode.Nodes.Find(key, false);
                    if (nodes != null)
                    {
                        if (nodes.Length != 0)
                        {
                            
                            nodes[0].Text=buddy.Name+ " ("+msg+")";
                        }
                    }
                }
                else if (type.Equals("offline"))
                {
                    //move to online
                    nodes = offlineNode.Nodes.Find(key, false);
                    if (nodes != null)
                    {
                        if (nodes.Length != 0)
                        {
                            nodes[0].Text=buddy.Name+ " ("+msg+")";
                        }
                    }
                }

            }
        }
        /// <summary>
        /// subscribe event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSubscr_Click(object sender, EventArgs e)
        {
            //get current selected node
            string key = (string)treeBuddies.SelectedNode.Name;

            TreeNode node = treeBuddies.SelectedNode.Parent;
            if (node == null)
            {
                return;
            }
            if(node.Name.Equals("Untrusted")){
                return;
            }
            //check whether subscrbe or unsubscribeurn;
            if (btnSubscr.Text.Equals("Subscribe"))
            {

                Program.mainForm.frmfeeds.subscManager.addSubscription("Newest Library additions", key);
                Common.GUI.MsgBoxOneButton msgForm = new Pbdms.Common.GUI.MsgBoxOneButton("Subscription successful", 'I');
                btnSubscr.Text = "Unsubscribe";
                msgForm.ShowDialog();
            }
            else
            {

                BusinessLogic.RSS.Subscription subscription = (BusinessLogic.RSS.Subscription)Program.mainForm.frmfeeds.subscManager.arrSubscriptions[(string)subscribeToNewAdditionsToolStripMenuItem.Tag];

                Program.mainForm.frmfeeds.subscManager.removeSubscription(subscription);
                Common.GUI.MsgBoxOneButton msgForm = new Pbdms.Common.GUI.MsgBoxOneButton("Unsubscription successful", 'I');
                btnSubscr.Text = "Subscribe";
                msgForm.ShowDialog();
            }
        }
        /// <summary>
        /// send message
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMsg_Click(object sender, EventArgs e)
        {
            string keyid = treeBuddies.SelectedNode.Name;
            TreeNode node = treeBuddies.SelectedNode.Parent;
            if (node == null)
            {
                return;
            }
            if (node.Name.Equals("Authenticated"))
            {
                //check if it is online
                Tools.FrmInstantMsg fmMsg = new Tools.FrmInstantMsg();
                fmMsg.MdiParent = this.MdiParent;

                fmMsg.setID(keyid);
                fmMsg.setTitle();
                fmMsg.Show();
            }
            else if (node.Name.Equals("Offline"))
            {
                //if it is offline
                Pbdms.Forms.Tools.FrmOfflineMsg frmOffline = new Pbdms.Forms.Tools.FrmOfflineMsg();
                frmOffline.MdiParent = this.MdiParent;

                frmOffline.addFriend(keyid);
                frmOffline.Show();
            }
            else
            {
               
            
                //untrusted
            }
        }
        /// <summary>
        /// send file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            string keyid = treeBuddies.SelectedNode.Name;
            TreeNode node = treeBuddies.SelectedNode.Parent;
            if (node.Name.Equals("Authenticated"))
            {
                DialogResult result = openFileDia.ShowDialog();
                string filelocation = null;
                if (result == DialogResult.OK)
                {

                    filelocation = openFileDia.FileName;
                    try
                    {
                        
                        Common.DataObject.Buddy buddy = Program.friendControl.getAFriendByKeyID(keyid);
                        FileInfo fileInfo = new FileInfo(filelocation);
                        FileTransferSenderGui fileTransfer = new FileTransferSenderGui(keyid, buddy.Name, fileInfo, Program.networkCtrller);



                        Program.mainForm.frmFileTransfer.MdiParent = Program.mainForm;
                        Program.mainForm.frmFileTransfer.addControl(fileTransfer);
                        Program.mainForm.frmFileTransfer.Activate();

                        Program.mainForm.frmFileTransfer.Show();

                    }
                    catch
                    {
                        MessageBox.Show("An unknown error occurred in sending a file");
                    }

                }
            }
            else if (node.Name.Equals("Offline"))
            {
                //if it is offline
                Pbdms.Forms.Tools.FrmOfflineMsg frmOffline = new Pbdms.Forms.Tools.FrmOfflineMsg();
                frmOffline.MdiParent = this.MdiParent;

                frmOffline.addFriend(keyid);
                frmOffline.Show();
            }
            else
            {


                //untrusted
            }
        }
    }
}